package br.ufc.customJDBC.routing;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

import br.ufc.customJDBC.CustomConnection;
import br.ufc.customJDBC.csv.CSVLog;

public class CircularQueueRouter implements Router{

	private List<CustomConnection> connectionPool;
	private int connectionPoolSize;
	private Iterator<CustomConnection> iter;
	private CSVLog csv;

	public CircularQueueRouter(Collection<CustomConnection> connectionPool, CSVLog csv) {
		this.connectionPool = new ArrayList<CustomConnection>(connectionPool);
		connectionPoolSize = connectionPool.size();
		iter = connectionPool.iterator();
		System.out.println("Circular Queue Router:");
		System.out.println("Number of nodes: " + connectionPoolSize);
		System.out.println("Connections:");
		for(CustomConnection cc : connectionPool){
			System.out.println(cc.getIp());
		}
		this.csv = csv;
	}

	private CustomConnection nextConnection(){
		synchronized (this) {
			if(iter.hasNext()){
				return iter.next();
			}else{
				iter = connectionPool.iterator();
				return iter.next();
			}			
		}		
	}

	@Override
	public boolean execute(String sql) throws SQLException {

		CustomConnection con = nextConnection();
		Statement statement = con.createStatement();

		long startTime = System.nanoTime();
		boolean ret = statement.execute(sql);
		long stopTime = System.nanoTime();

		String nodes = "[ " + con.getIp() + " ]";
		csv.writeLine(sql, (stopTime - startTime), 1, "execute", nodes, connectionPoolSize );
		//		statement.close();
		return ret;
	}

	@Override
	public ResultSet executeQuery(String sql) throws SQLException {
		CustomConnection con = nextConnection();
		Statement statement = con.createStatement();

		long startTime = System.nanoTime();
		ResultSet ret = statement.executeQuery(sql);
		long stopTime = System.nanoTime();
//		System.out.println("Router: " + (stopTime - startTime));

		String nodes = "[ " + con.getIp() + " ]";
		csv.writeLine(sql, (stopTime - startTime), 1, "executeQuery", nodes, connectionPoolSize );
		//		statement.close();
		return ret;
	}

	@Override
	public int executeUpdate(String sql) throws SQLException {
		CustomConnection con = nextConnection();
		Statement statement = con.createStatement();

		long startTime = System.nanoTime();
		int ret = statement.executeUpdate(sql);
		long stopTime = System.nanoTime();

		String nodes = "[ " + con.getIp() + " ]";
		csv.writeLine(sql, (stopTime - startTime), 1, "executeUpdate", nodes, connectionPoolSize );

		//		statement.close();
		return ret;
	}
}
